package com.ljm.sys.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljm.common.enums.DataStatus;
import com.ljm.common.enums.ResultStatus;
import com.ljm.common.excuption.Assert;
import com.ljm.common.page.PageDto;
import com.ljm.common.util.BeanUtils;
import com.ljm.common.util.StringUtil;
import com.ljm.sys.auth.api.SysAuthResourceApi;
import com.ljm.sys.auth.dto.SysAuthResourceDto;
import com.ljm.sys.auth.entity.SysAuthResource;
import com.ljm.sys.auth.mapper.SysAuthResourceMapper;
import com.ljm.sys.auth.service.ISysAuthResourceService;
import com.ljm.sys.org.dto.SysOrgUserDto;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
    * 系统菜单 服务实现类
    * </p>
 *
 * @author ming
 * @since 2019-03-28
 */
@Service
@Transactional
public class SysAuthResourceServiceImpl extends ServiceImpl<SysAuthResourceMapper, SysAuthResource>
        implements ISysAuthResourceService, SysAuthResourceApi {
    /**
     * 资源数据接口
     */
    @Resource
    private SysAuthResourceMapper sysAuthResourceMapper;

    @Override
    public void saveData(SysAuthResourceDto dto, SysOrgUserDto curUser) {
        SysAuthResource po=new SysAuthResource();
        BeanUtils.copyProperties(dto,po);
        if(StringUtil.isEmpty(dto.getId())){
            po.setCreateTime(LocalDateTime.now());
            po.setCreater(curUser.getLoginName());
            po.setStatus(DataStatus.NORMAL.getCode());
            po.setOrgId(curUser.getOrgId());
            po.setId(IdWorker.getId());
        }
        //设置上级菜单
        if(0==po.getParentId()){
            po.setFullName("0");
        }else{
            SysAuthResource parent=this.getById(po.getParentId());
            po.setFullName(parent.getFullName()+"->"+po.getParentId());
            //修改父资源 是否有子资源字段
            parent.setIsLeaf(0);
            this.updateById(parent);
        }
        po.setEditor(curUser.getLoginName());
        po.setEditTime(LocalDateTime.now());
        // 校验是否有子资源
        if(this.getTotalChild(po.getId())>0){
            po.setIsLeaf(0);
        }else{
            po.setIsLeaf(1);
        }

        this.saveOrUpdate(po);
    }

    private Integer getTotalChild(Long id){
        QueryWrapper<SysAuthResource> wrapper=new QueryWrapper<>();
        wrapper.eq("parent_id",id);
        return this.count(wrapper);
    }

    @Override
    public void del(List<Long> ids) {
        if(StringUtil.isEmpty(ids)){
            Assert.throwException(ResultStatus.FIAL.getCode(),"主键集合为空");
        }
        ids.stream().forEach(id ->{
            if(this.getTotalChild(id)>0){
                Assert.throwException(ResultStatus.FIAL.getCode(),"请先删除子资源");
            }else{
                // 设置父资源 是否有子资源字段
                SysAuthResource po=this.getById(id);
                if(po.getParentId()!=0){
                    if(this.getTotalChild(po.getParentId())<=1){ //除了自己  没有其他子资源
                        SysAuthResource parent=new SysAuthResource();
                        parent.setId(po.getParentId());
                        parent.setIsLeaf(1);
                        this.updateById(parent);
                    }
                }
                this.removeById(id);
            }
        });
    }

    @Override
    public SysAuthResourceDto getDataById(Long id) {
        SysAuthResourceDto dto=new SysAuthResourceDto();
        SysAuthResource po=this.getById(id);
        if(!StringUtil.isEmpty(po)){
            BeanUtils.copyProperties(po,dto);
        }
        return dto;
    }

    @Override
    public PageDto<SysAuthResourceDto> getDataByPage(String title, String path, String groupName, String permissionCode,
                                                  Integer pageNo, Integer pageSize) {
        PageDto<SysAuthResourceDto> pageDto=new PageDto<>(pageNo,pageSize);
        IPage<SysAuthResource> page=new Page<>(pageNo,pageSize);
        QueryWrapper<SysAuthResource> wrapper=new QueryWrapper<>();
        if(!StringUtil.isEmpty(title)){
            wrapper.like("title",title);
        }
        if(!StringUtil.isEmpty(path)){
            wrapper.like("path",path);
        }
        if(!StringUtil.isEmpty(groupName)){
            wrapper.like("group_name",groupName);
        }
        if(!StringUtil.isEmpty(permissionCode)){
            wrapper.like("permission_code",permissionCode);
        }
        wrapper.eq("parent_id",0);
        wrapper.orderByAsc("sort");
        wrapper.orderByDesc("title");
        page=this.page(page,wrapper);
        if(!StringUtil.isEmpty(page.getRecords())){
            pageDto.setTotal(page.getTotal());
            pageDto.setRecords(BeanUtils.copyPropertiesByList(page.getRecords(),SysAuthResourceDto.class));
        }
        return pageDto;
    }

    @Override
    public List<SysAuthResourceDto> getAllResource() {
        List<SysAuthResourceDto> list=new ArrayList<>();
        QueryWrapper<SysAuthResource> wrapper=new QueryWrapper<>();
        wrapper.ne("resource_type",2);
        List<SysAuthResource> pos=this.list(wrapper);
        if(!StringUtil.isEmpty(pos)){
            list=BeanUtils.copyPropertiesByList(pos,SysAuthResourceDto.class);
        }
        return list;
    }

    @Override
    public List<SysAuthResourceDto> getCurUserResource(SysOrgUserDto curUser) {
        List<SysAuthResourceDto> menu=new ArrayList<>();
        List<SysAuthResourceDto> list=sysAuthResourceMapper.getCurUserResource(curUser.getId());
        if(!StringUtil.isEmpty(list)){
            //递归处理菜单
            this.setMenu(list,menu);
        }
        return menu;
    }

    @Override
    public List<SysAuthResourceDto> getChlildRes(Long parentId) {
        List<SysAuthResourceDto> dtos=new ArrayList<>();
        QueryWrapper<SysAuthResource> wrapper=new QueryWrapper<>();
        wrapper.eq("parent_id",parentId);
        wrapper.orderByAsc("sort");
        wrapper.orderByDesc("title");
        List<SysAuthResource> pos=this.list(wrapper);
        if(!StringUtil.isEmpty(pos)){
            dtos=BeanUtils.copyPropertiesByList(this.list(wrapper),SysAuthResourceDto.class);
        }
        return dtos;
    }

    @SuppressWarnings("all")	// 忽略全部规则
    private void setMenu(List<SysAuthResourceDto> sourceData,List<SysAuthResourceDto> target){
       if(sourceData.size()<=0){
           return;
       }else if(target.size()<=0){ //根节点
        for(int i=0;i<sourceData.size();i++){
            if(sourceData.get(i).getParentId()==0){
                target.add(sourceData.get(i));
                sourceData.remove(sourceData.get(i--));
                continue;
            }
        }
        if(target.size()<=0){
           return;
        }
        //遍历子菜单
        setMenu(sourceData,target);
       } else{ //叶子节点
            for(int i=0;i<target.size();i++){
                for(int j=0;j<sourceData.size();j++){
                    if(sourceData.get(j).getParentId()==target.get(i).getId()){
                        // 判断当前菜单是否存在子菜单
                        if (target.get(i).getChildren() == null) {
                            List<SysAuthResourceDto> appSubMenus = new ArrayList<>();
                            appSubMenus.add(sourceData.get(j));
                            target.get(i).setChildren(appSubMenus);
                        } else {
                            target.get(i).getChildren().add(sourceData.get(j));
                        }
                        // 下级菜单
                        List<SysAuthResourceDto> tempList=new ArrayList<SysAuthResourceDto>();
                        tempList.add(sourceData.get(j));
                        sourceData.remove(sourceData.get(j--));//去除已经匹配的数据
                        setMenu(sourceData, tempList);
                    }
                }
            }
        }
    }
}
